#include "sqlhighlighter.h"

SqlHighlighter::SqlHighlighter(QTextDocument *parent)
    : QSyntaxHighlighter(parent)
{
    // 关键字格式
    keywordFormat.setForeground(Qt::darkBlue);
    keywordFormat.setFontWeight(QFont::Bold);

    // SQL 关键字
    QStringList keywords = {
        "SELECT", "FROM", "WHERE", "INSERT", "INTO", "VALUES",
        "UPDATE", "SET", "DELETE", "JOIN", "ON", "ORDER", "BY",
        "GROUP", "HAVING", "LIMIT", "AND", "OR", "NOT", "IN", "IS",
        "NULL", "AS", "DISTINCT", "COUNT", "SUM", "AVG", "MAX", "MIN"
    };

    // 函数格式
    functionFormat.setForeground(Qt::darkMagenta);
    functionFormat.setFontWeight(QFont::Bold);

    QStringList functions = {
        "COUNT", "SUM", "AVG", "MAX", "MIN"
    };

    // 注释格式
    commentFormat.setForeground(Qt::gray);

    // 字符串格式
    quotationFormat.setForeground(Qt::darkGreen);

    // 数字格式
    numberFormat.setForeground(Qt::red);

    // 添加规则
    for (const QString &pattern : keywords) {
        HighlightingRule rule;
        rule.pattern = QRegularExpression("\\b" + pattern + "\\b", QRegularExpression::CaseInsensitiveOption);
        rule.format = keywordFormat;
        highlightingRules.append(rule);
    }

    for (const QString &pattern : functions) {
        HighlightingRule rule;
        rule.pattern = QRegularExpression("\\b" + pattern + "\\b", QRegularExpression::CaseInsensitiveOption);
        rule.format = functionFormat;
        highlightingRules.append(rule);
    }

    // 注释匹配
    commentStartExpression = QRegularExpression("--[^\n]*");
    commentEndExpression = QRegularExpression("\n");
}

void SqlHighlighter::highlightBlock(const QString &text)
{
    // 应用通用规则
    for (const HighlightingRule &rule : highlightingRules) {
        QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text);
        while (matchIterator.hasNext()) {
            QRegularExpressionMatch match = matchIterator.next();
            setFormat(match.capturedStart(), match.capturedLength(), rule.format);
        }
    }

    // 高亮字符串
    int startIndex = 0;
    QChar quoteChar = QChar('"');
    while (startIndex < text.length()) {
        int quoteStart = text.indexOf(quoteChar, startIndex);
        if (quoteStart == -1)
            break;
        int quoteEnd = text.indexOf(quoteChar, quoteStart + 1);
        if (quoteEnd == -1)
            quoteEnd = text.length();
        setFormat(quoteStart, quoteEnd - quoteStart + 1, quotationFormat);
        startIndex = quoteEnd + 1;
    }

    // 高亮数字
    QRegularExpression numberRegex("\\b\\d+\\b");
    QRegularExpressionMatchIterator numberMatchIterator = numberRegex.globalMatch(text);
    while (numberMatchIterator.hasNext()) {
        QRegularExpressionMatch match = numberMatchIterator.next();
        setFormat(match.capturedStart(), match.capturedLength(), numberFormat);
    }

    // 高亮注释
    int commentStart = commentStartExpression.match(text, 0).capturedStart();
    if (commentStart >= 0) {
        int commentEnd = commentEndExpression.match(text, commentStart).capturedStart();
        if (commentEnd == -1)
            commentEnd = text.length();
        setFormat(commentStart, commentEnd - commentStart, commentFormat);
    }
}
#ifndef SQLHIGHLIGHTER_H
#define SQLHIGHLIGHTER_H

#include <QSyntaxHighlighter>
#include <QTextCharFormat>
#include <QRegularExpression>

class SqlHighlighter : public QSyntaxHighlighter
{
    Q_OBJECT

public:
    explicit SqlHighlighter(QTextDocument *parent = nullptr);

protected:
    void highlightBlock(const QString &text) override;

private:
    struct HighlightingRule
    {
        QRegularExpression pattern;
        QTextCharFormat format;
    };
    QVector<HighlightingRule> highlightingRules;

    QRegularExpression commentStartExpression;
    QRegularExpression commentEndExpression;
    QTextCharFormat keywordFormat;
    QTextCharFormat functionFormat;
    QTextCharFormat commentFormat;
    QTextCharFormat quotationFormat;
    QTextCharFormat numberFormat;
};

#endif // SQLHIGHLIGHTER_H
QTextEdit* SqlEditor::getTextEdit() const
{
    return m_sqlTextEdit;
}
#include "sqlautocomplete.h"
#include "sqlhighlighter.h"
#include <QSqlDriver>
#include <QSqlQuery>
#include <QDebug>

SqlAutoComplete::SqlAutoComplete(QObject *parent)
    : QObject(parent)
{
    m_model = new QStringListModel(this);
    m_completer = new QCompleter(m_model, parent);
    m_completer->setCaseSensitivity(Qt::CaseInsensitive);
    loadKeywords();
}

SqlAutoComplete::~SqlAutoComplete()
{
}

QCompleter* SqlAutoComplete::completer() const
{
    return m_completer;
}

void SqlAutoComplete::setDatabase(const QSqlDatabase &db)
{
    m_database = db;
    loadDatabaseSchema();
}

void SqlAutoComplete::loadKeywords()
{
    QStringList keywords = {
        "SELECT", "FROM", "WHERE", "INSERT", "INTO", "VALUES",
        "UPDATE", "SET", "DELETE", "JOIN", "ON", "ORDER", "BY",
        "GROUP", "HAVING", "LIMIT", "AND", "OR", "NOT", "IN", "IS",
        "NULL", "AS", "DISTINCT", "COUNT", "SUM", "AVG", "MAX", "MIN"
    };

    QStringList current = m_model->stringList();
    current.append(keywords);
    current.removeDuplicates();
    m_model->setStringList(current);
}

void SqlAutoComplete::loadDatabaseSchema()
{
    if (!m_database.isOpen()) {
        qDebug() << "Database is not open.";
        return;
    }

    QStringList tables = m_database.tables();
    QStringList current = m_model->stringList();

    for (const QString &table : tables) {
        current.append(table);
        QSqlQuery query(m_database);
        QString sql = "PRAGMA table_info(" + table + ")";
        if (query.exec(sql)) {
            while (query.next()) {
                current.append(query.value(1).toString());
            }
        }
    }

    current.removeDuplicates();
    m_model->setStringList(current);
}
#ifndef SQLAUTOCOMPLETE_H
#define SQLAUTOCOMPLETE_H

#include <QObject>
#include <QSqlDatabase>
#include <QCompleter>

class SqlAutoComplete : public QObject
{
    Q_OBJECT
public:
    explicit SqlAutoComplete(QObject *parent = nullptr);
    ~SqlAutoComplete();

    QCompleter* completer() const;
    void setDatabase(const QSqlDatabase &db);

private:
    void loadKeywords();
    void loadDatabaseSchema();

    QCompleter* m_completer;
    QStringListModel* m_model;
    QSqlDatabase m_database;
};

#endif // SQLAUTOCOMPLETE_H
#include "sqlformatter.h"
#include "sqlautocomplete.h"
#include <QCompleter>
#include <QStringListModel>

SQLFormatter::SQLFormatter()
{
}

QString SQLFormatter::format(const QString &sql)
{
    // 简单的SQL格式化实现
    QString formatted = sql;
    
    // 替换多个空格为单个空格
    while (formatted.contains("  ")) {
        formatted.replace("  ", " ");
    }
    
    // 转换为小写的SQL关键字
    QStringList keywords = {"SELECT", "FROM", "WHERE", "INSERT", "INTO", 
                           "VALUES", "UPDATE", "SET", "DELETE", "JOIN",
                           "ON", "ORDER", "BY", "GROUP", "HAVING", "LIMIT"};
    
    foreach (const QString &keyword, keywords) {
        formatted.replace(QRegExp("\\b" + keyword + "\\b", Qt::CaseInsensitive), keyword.toLower());
    }
    
    // 在逗号后添加空格
    formatted.replace(QRegExp(",(\\S)"), ", \\1");
    
    // 在SQL关键字前后添加换行
    foreach (const QString &keyword, keywords) {
        formatted.replace(QRegExp("\\b" + keyword + "\\b"), "\n" + keyword.toLower() + " ");
    }
    
    // 移除开头的空格和换行
    if (formatted.startsWith(" ") || formatted.startsWith("\n")) {
        formatted.remove(0, 1);
    }
    
    return formatted;
}
#ifndef SQLFORMATTER_H
#define SQLFORMATTER_H

#include <QString>

class SQLFormatter
{
public:
    SQLFormatter();
    QString format(const QString &sql);
};

#endif // SQLFORMATTER_H
#include "sqleditor.h"
#include "sqlformatter.h"
#include "sqlautocomplete.h"
#include "sqlhighlighter.h"
#include "sqltextedit.h"
#include <QTextEdit>
#include <QPushButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QSqlQueryModel>
#include <QSqlError>
#include <QDateTime>
#include <QSqlQuery>
#include <QSplitter>
#include <QTableView>
#include <QHeaderView>
#include <QMessageBox>
#include <QCompleter>
#include <QStringListModel>
#include <QTextDocument>

SqlEditor::SqlEditor(QWidget *parent)
    : QWidget(parent)
    , m_resultModel(nullptr)
    , m_sqlFormatter(new SQLFormatter())
    , m_autoComplete(new SqlAutoComplete(this))
    , m_highlighter(nullptr)
{
    setupUI();
    
    // 设置自动补全器
    SqlTextEdit *textEdit = getTextEdit();
    textEdit->setCompleter(m_autoComplete->completer());
    
    // 设置语法高亮器
    m_highlighter = new SqlHighlighter(m_sqlTextEdit->document());
}

QString SqlEditor::getSqlText() const
{
    return m_sqlTextEdit->toPlainText();
}

void SqlEditor::setSqlText(const QString &text)
{
    m_sqlTextEdit->setPlainText(text);
}

QSqlQueryModel* SqlEditor::getQueryModel() const
{
    return m_resultModel;
}

void SqlEditor::setDatabase(const QSqlDatabase &db)
{
    m_database = db;
    // 更新自动补全器的数据库信息
    m_autoComplete->setDatabase(db);
}

SqlTextEdit* SqlEditor::getTextEdit() const
{
    return m_sqlTextEdit;
}

void SqlEditor::onQueryExecuted(QSqlQueryModel *model)
{
    m_resultModel = model;
    
    // 创建一个表格视图来显示结果
    if (!m_resultView) {
        m_resultView = new QTableView;
        m_resultView->setModel(m_resultModel);
        m_resultView->setSelectionBehavior(QAbstractItemView::SelectRows);
        m_resultView->setSelectionMode(QAbstractItemView::SingleSelection);
        m_resultView->setAlternatingRowColors(true);
        m_resultView->horizontalHeader()->setStretchLastSection(true);
        m_resultView->verticalHeader()->setVisible(false);
        
        // 将结果视图添加到分割器中
        m_splitter->addWidget(m_resultView);
    } else {
        m_resultView->setModel(m_resultModel);
    }
    
    if (m_resultModel->lastError().isValid()) {
        m_resultLabel->setText(tr("Error: %1").arg(m_resultModel->lastError().text()));
    } else {
        m_resultLabel->setText(tr("Query executed successfully. Rows affected: %1").arg(m_resultModel->rowCount()));
    }
}

void SqlEditor::formatSql()
{
    QString sql = m_sqlTextEdit->toPlainText();
    if (!sql.isEmpty()) {
        QString formattedSql = m_sqlFormatter->format(sql);
        m_sqlTextEdit->setPlainText(formattedSql);
    }
}

void SqlEditor::executeButtonClicked()
{
    QString sql = getSqlText().trimmed();
    if (!sql.isEmpty()) {
        emit executeQuery(sql);
    }
}

void SqlEditor::setupUI()
{
    QVBoxLayout *mainLayout = new QVBoxLayout(this);
    mainLayout->setContentsMargins(0, 0, 0, 0);
    
    m_splitter = new QSplitter(Qt::Vertical);
    
    // SQL编辑区域
    QWidget *editorWidget = new QWidget;
    QVBoxLayout *editorLayout = new QVBoxLayout(editorWidget);
    editorLayout->setContentsMargins(0, 0, 0, 0);
    
    m_sqlTextEdit = new SqlTextEdit;
    m_sqlTextEdit->setPlaceholderText(tr("Enter your SQL query here..."));
    
    // 按钮布局
    QHBoxLayout *buttonLayout = new QHBoxLayout;
    m_executeButton = new QPushButton(tr("Execute"));
    m_formatButton = new QPushButton(tr("Format SQL"));  // 添加格式化按钮
    
    buttonLayout->addWidget(m_executeButton);
    buttonLayout->addWidget(m_formatButton);
    buttonLayout->addStretch();
    
    editorLayout->addWidget(m_sqlTextEdit);
    editorLayout->addLayout(buttonLayout);
    
    m_splitter->addWidget(editorWidget);
    
    // 结果显示区域
    QWidget *resultWidget = new QWidget;
    QVBoxLayout *resultLayout = new QVBoxLayout(resultWidget);
    resultLayout->setContentsMargins(0, 0, 0, 0);
    
    m_resultLabel = new QLabel(tr("Execute a query to see results"));
    m_resultLabel->setWordWrap(true);
    
    resultLayout->addWidget(m_resultLabel);
    
    m_splitter->addWidget(resultWidget);
    
    // 设置分割器的初始大小
    m_splitter->setSizes(QList<int>() << 200 << 100);
    
    mainLayout->addWidget(m_splitter);
    
    // 连接信号和槽
    connect(m_executeButton, &QPushButton::clicked, this, &SqlEditor::executeButtonClicked);
    connect(m_formatButton, &QPushButton::clicked, this, &SqlEditor::formatSql);  // 连接格式化按钮
}